package baidu.reader.txt.model
{
    import baidu.lib.serialization.*;
    import baidu.reader.common.*;
    import baidu.reader.common.model.*;
    import baidu.ui.managers.*;
    import flash.events.*;
    import flash.utils.*;

    public class TxtDataModel extends EventDispatcher implements IPageProvider
    {
        private var dataProxy:TxtRemoteDataProxy;
        private var _current_docid:String;
        private var _default_rn:int = 50;
        private var _totalPage:int;
        private var _pageFirstCharArray:Array;
        private var _textArray:Array;
        private var _currentBlock:int;
        private var _blockCacheStart:int = -100;
        private var _blockCacheEnd:int = -100;
        private var _currentTextData:String;
        private var _cumulativeTextData:String = "";
        private var _isLoading:Boolean = false;
        private var _pageStartArrays:Array;

        public function TxtDataModel(param1:IEventDispatcher = null)
        {
            this._pageFirstCharArray = [NaN, 0];
            this._textArray = [];
            this._pageStartArrays = [];
            super(param1);
            this.init();
            return;
        }

        private function init() : void
        {
            this.dataProxy = new TxtRemoteDataProxy();
            this.dataProxy.addEventListener(Event.COMPLETE, this.dataCompleteHandler);
            this.dataProxy.addEventListener(ErrorEvent.ERROR, this.dataErrorHandler);
            var _loc_1:* = InstanceManager.createSingletonInstance(AppConfigModel);
            this._default_rn = _loc_1.default_rn;
            return;
        }

        private function dataErrorHandler(event:Event) : void
        {
            this._isLoading = false;
            dispatchEvent(new ErrorEvent(ErrorEvent.ERROR));
            return;
        }

        private function dataCompleteHandler(event:Event) : void
        {
//            var docInfo:Object;
//            var tmpBinaryData:ByteArray;
//            var contentStr:String;
//            var event:* = event;
//            this._currentTextData = "";
//            this._textArray = [];
//            var rawByteArray:* = this.dataProxy.data;
//            rawByteArray.endian = Endian.LITTLE_ENDIAN;
//            var docInfoBinaryData:* = new ByteArray();
//            docInfoBinaryData.endian = Endian.LITTLE_ENDIAN;
//            rawByteArray.position = 0;
//            if (rawByteArray.bytesAvailable > 106 + rawByteArray.position)
//            {
//                rawByteArray.readBytes(docInfoBinaryData, 0, 106);
//            }
//            else
//            {
//                trace("binaryData.bytesAvailable: " + rawByteArray.bytesAvailable);
//                trace("��ݸ�ʽ�����ļ�̫С");
//                this._isLoading = false;
//                dispatchEvent(new Event(ErrorEvent.ERROR));
//                return;
//            }
//            var docInfoStr:* = docInfoBinaryData.readMultiByte(docInfoBinaryData.bytesAvailable, "utf-8");
//            try
//            {
//                docInfo = JSON.decode(docInfoStr);
//            }
//            catch (e:Error)
//            {
//                trace("�����ĵ���Ϣʧ��");
//            }
//            this._totalPage = int(docInfo["totalPage"]);
//            var si:* = rawByteArray.position;
//            this._pageFirstCharArray = [NaN, 0];
//            var i:* = (si + 1);
//            var iLen:* = rawByteArray.length;
//            while (i < iLen)
//            {
//                
//                if (rawByteArray[i] == 0)
//                {
//                    tmpBinaryData = new ByteArray();
//                    tmpBinaryData.endian = Endian.LITTLE_ENDIAN;
//                    rawByteArray.position = si;
//                    rawByteArray.readBytes(tmpBinaryData, 0, i - si);
//                    si = si + (i - si);
//                    rawByteArray.position = si + 1;
//                    tmpBinaryData.position = 0;
//                    while (tmpBinaryData[tmpBinaryData.position] == 0 && tmpBinaryData.bytesAvailable)
//                    {
//                        
//                        var _loc_3:* = tmpBinaryData;
//                        var _loc_4:* = tmpBinaryData.position + 1;
//                        _loc_3.position = _loc_4;
//                    }
//                    contentStr = tmpBinaryData.readMultiByte(tmpBinaryData.bytesAvailable, "utf-8");
//                    contentStr = contentStr.replace(/\r/g, "");
//                    this._pageFirstCharArray.push(this._pageFirstCharArray[(this._pageFirstCharArray.length - 1)] + contentStr.length);
//                    this._textArray.push(contentStr);
//                }
//                i = (i + 1);
//            }
//            this.updatePageStartArrays();
//            this._currentTextData = this._textArray.join("");
//            if (this._currentBlock == (this._blockCacheStart - 1))
//            {
//                this._blockCacheStart = this._currentBlock;
//                dispatchEvent(new ReaderEvent(ReaderEvent.TEXT_ADD, TxtChapterModel.TOP));
//            }
//            else if (this._currentBlock == (this._blockCacheEnd + 1))
//            {
//                this._blockCacheEnd = this._currentBlock;
//                dispatchEvent(new ReaderEvent(ReaderEvent.TEXT_ADD, TxtChapterModel.BOTTOM));
//            }
//            else
//            {
//                this._blockCacheEnd = this._currentBlock;
//                this._blockCacheStart = this._currentBlock;
//                dispatchEvent(new ReaderEvent(ReaderEvent.TEXT_ADD, TxtChapterModel.REPLACE));
//            }
//            this._isLoading = false;
//            dispatchEvent(event);
//            return;
			var contentStr:String;
			var docInfo:Object;
			var docInfoBinaryData:flash.utils.ByteArray;
			var docInfoStr:String;
			var event:flash.events.Event;
			var i:int;
			var iLen:int;
			var rawByteArray:flash.utils.ByteArray;
			var si:int;
			var tmpBinaryData:flash.utils.ByteArray;
			
			var loc1:*;
			docInfo = null;
			tmpBinaryData = null;
			contentStr = null;
			this._currentTextData = "";
			this._textArray = [];
			rawByteArray = this.dataProxy.data;
			rawByteArray.endian = flash.utils.Endian.LITTLE_ENDIAN;
			docInfoBinaryData = new flash.utils.ByteArray();
			docInfoBinaryData.endian = flash.utils.Endian.LITTLE_ENDIAN;
			rawByteArray.position = 0;
			if (rawByteArray.bytesAvailable > 106 + rawByteArray.position)
			{
				rawByteArray.readBytes(docInfoBinaryData, 0, 106);
			}
			else 
			{
				trace("binaryData.bytesAvailable: " + rawByteArray.bytesAvailable);
				trace("数据格式错误，文件太小");
				this._isLoading = false;
				dispatchEvent(new flash.events.Event(flash.events.ErrorEvent.ERROR));
				return;
			}
			docInfoStr = docInfoBinaryData.readMultiByte(docInfoBinaryData.bytesAvailable, "utf-8");
			try
			{
				docInfo = baidu.lib.serialization.JSON.decode(docInfoStr);
			}
			catch (e:Error)
			{
				trace("解析文档信息失败");
			}
			this._totalPage = int(docInfo["totalPage"]);
			si = rawByteArray.position;
			this._pageFirstCharArray = [NaN, 0];
			i = si + 1;
			iLen = rawByteArray.length;
			while (i < iLen) 
			{
				if (rawByteArray[i] == 0)
				{
					tmpBinaryData = new flash.utils.ByteArray();
					tmpBinaryData.endian = flash.utils.Endian.LITTLE_ENDIAN;
					rawByteArray.position = si;
					rawByteArray.readBytes(tmpBinaryData, 0, i - si);
					si = si + i - si;
					rawByteArray.position = si + 1;
					tmpBinaryData.position = 0;
					while (tmpBinaryData[tmpBinaryData.position] == 0 && tmpBinaryData.bytesAvailable) 
					{
						var loc2:*;
						var loc3:*=((loc2 = tmpBinaryData).position + 1);
						loc2.position = loc3;
					}
					contentStr = tmpBinaryData.readMultiByte(tmpBinaryData.bytesAvailable, "utf-8");
					contentStr = contentStr.replace(new RegExp("\\r", "g"), "");
					this._pageFirstCharArray.push(this._pageFirstCharArray[(this._pageFirstCharArray.length - 1)] + contentStr.length);
					this._textArray.push(contentStr);
				}
				i = (i + 1);
			}
			this.updatePageStartArrays();
			this._currentTextData = this._textArray.join("");
			if (this._currentBlock != (this._blockCacheStart - 1))
			{
				if (this._currentBlock != this._blockCacheEnd + 1)
				{
					this._blockCacheEnd = this._currentBlock;
					this._blockCacheStart = this._currentBlock;
					dispatchEvent(new baidu.reader.common.ReaderEvent(baidu.reader.common.ReaderEvent.TEXT_ADD, baidu.reader.txt.model.TxtChapterModel.REPLACE));
				}
				else 
				{
					this._blockCacheEnd = this._currentBlock;
					dispatchEvent(new baidu.reader.common.ReaderEvent(baidu.reader.common.ReaderEvent.TEXT_ADD, baidu.reader.txt.model.TxtChapterModel.BOTTOM));
				}
			}
			else 
			{
				this._blockCacheStart = this._currentBlock;
				dispatchEvent(new baidu.reader.common.ReaderEvent(baidu.reader.common.ReaderEvent.TEXT_ADD, baidu.reader.txt.model.TxtChapterModel.TOP));
			}
			this._isLoading = false;
			dispatchEvent(event);
			return;
        }

        public function loadNextBlock() : void
        {
            this.loadBlock(this._current_docid, (this._blockCacheEnd + 1));
            return;
        }

        public function loadPreviousBlock() : void
        {
            if (this._blockCacheStart <= 0)
            {
                dispatchEvent(new Event(ErrorEvent.ERROR));
                return;
            }
            this.loadBlock(this._current_docid, (this._blockCacheStart - 1));
            return;
        }

        public function loadBlock(param1:String, param2:int) : void
        {
            if (!this._isLoading)
            {
                if (param2 <= this._blockCacheEnd && param2 >= this.blockCacheStart && param1 == this.currentDocid)
                {
                    this._currentBlock = param2;
                    dispatchEvent(new ReaderEvent(ReaderEvent.TEXT_ADD, TxtChapterModel.NO_ACTION));
                    this._isLoading = false;
                    dispatchEvent(new Event(Event.COMPLETE));
                    return;
                }
                if (this._blockCacheStart - param2 > 1 || param2 - this._blockCacheEnd > 1 || param1 != this.currentDocid)
                {
                    this.reset();
                }
                this.dataProxy.load(param1, param2, this._default_rn);
                this._isLoading = true;
                this._currentBlock = param2;
                this._current_docid = param1;
            }
            return;
        }

        public function loadPage(param1:String, param2:int) : void
        {
            var _loc_3:int = 0;
            while (param2 > (_loc_3 + 1) * this._default_rn)
            {
                
                _loc_3++;
            }
            if (param1 != this._current_docid)
            {
                this.reset();
                this.loadBlock(param1, _loc_3);
            }
            else
            {
                this.loadBlock(param1, _loc_3);
            }
            return;
        }

        private function updatePageStartArrays() : void
        {
            this._pageStartArrays[this._currentBlock] = this._pageFirstCharArray.concat();
            return;
        }

        public function reset() : void
        {
            this._blockCacheStart = -100;
            this._blockCacheEnd = -100;
            this._pageStartArrays = [];
            return;
        }

        public function get currentBlockTextData() : String
        {
            return this._currentTextData;
        }

        public function get cumulativeTextData() : String
        {
            return this._cumulativeTextData;
        }

        public function get totalPage() : int
        {
            return this._totalPage;
        }

        public function get pageFirstCharArray() : Array
        {
            return this._pageFirstCharArray;
        }

        public function get currentBlock() : int
        {
            return this._currentBlock;
        }

        public function get default_rn() : int
        {
            return this._default_rn;
        }

        public function get currentDocid() : String
        {
            return this._current_docid;
        }

        public function get blockCacheStart() : int
        {
            return this._blockCacheStart;
        }

        public function get blockCacheEnd() : int
        {
            return this._blockCacheEnd;
        }

        public function get pageStartArrays() : Array
        {
            return this._pageStartArrays;
        }

    }
}
